#include "serviceclient.h"


#include <QStringList>
#include <QRegExp>
#include <QCryptographicHash>

ServiceClient::ServiceClient(QTcpSocket *socket, QObject *parent) : Client(socket, parent)
{
    connect(p_socket, SIGNAL(readyRead()), this, SLOT(processIncomingData()));

    v_state = Handshake;
}


QString computeAcceptV2(QString key)
{
    key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    QByteArray hash = QCryptographicHash::hash ( key.toUtf8(), QCryptographicHash::Sha1 );
    return hash.toBase64();
}

void ServiceClient::processIncomingData(){
    v_lastUnprocessedData = p_socket->readAll();
    QStringList requests;
    QString handshake;
    QRegExp keyRegexp("Sec-WebSocket-Key: (.+)\r\n");
    keyRegexp.setMinimal(true);
    QString key;
    QString acceptKey;
    QByteArray decodedData;
    QByteArray encodedData;
    int frameSize;
    int maskIndex;
    int dataIndex;
    char mask[4];
    int maskCurrentIndex;


    switch(v_state){
    case Handshake:
        requests = QString(v_lastUnprocessedData).split(QRegExp("\n[\n\r]*\n"), QString::KeepEmptyParts);
        qDebug() << "RECEIVED" << v_lastUnprocessedData;

        if(requests.count() == 2){
            v_lastUnprocessedData = requests.at(1).toLatin1();
            handshake = requests.at(0);
            keyRegexp.indexIn(handshake);
            key = keyRegexp.capturedTexts().at(1);
            //key = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
            qDebug() <<"KEY = " << key;
            acceptKey = computeAcceptV2(key);
        }

        qDebug() << "DATA << " << acceptKey;

        p_socket->write(QString("HTTP/1.1 101 Switching Protocols\r\n"
                                "Upgrade: websocket\r\n"
                                "Connection: Upgrade\r\n"
                                "Sec-WebSocket-Accept: " + acceptKey + "\r\n\r\n").toLatin1());
        v_lastUnprocessedData.clear();
        v_state = Opened;
        break;
    case Opened:
        if(v_lastUnprocessedData.at(1) == 126) // 2 next bytes are used for size
        {
            maskIndex = 4;
        }
        else if(v_lastUnprocessedData.at(1) == 127) // 8 next bytes are used for size
        {
            maskIndex = 10;
        }
        else{
            maskIndex = 2;
        }
        mask[0] = v_lastUnprocessedData.at(maskIndex);
        mask[1] = v_lastUnprocessedData.at(maskIndex+1);
        mask[2] = v_lastUnprocessedData.at(maskIndex+2);
        mask[3] = v_lastUnprocessedData.at(maskIndex+3);

        dataIndex = maskIndex + 4;
        encodedData = v_lastUnprocessedData.mid(dataIndex);
        maskCurrentIndex = 0;
        for(int i=0; i<encodedData.count(); i++){
            decodedData.append(encodedData.at(i) ^ mask[maskCurrentIndex % 4]);
            maskCurrentIndex++;
        }

        v_lastUnprocessedData.clear();
        qDebug() << decodedData;
        Q_EMIT dataReceived(decodedData);
        break;

    }

}



void ServiceClient::send(QByteArray data){
    p_socket->write(data);
}
